using Reversi;

// ===================================================================
// Game AI code.
// Note: These are executed in the worker thread.
// ===================================================================
//
// Modified: 2009/09/28, Jeremiah Blanchard (Full Sail)
namespace Reversi
{
    public class Agent
    {
        // AI agent's behavior.
        private Behavior behavior;

        // AI agent's knowledge.
        internal int scoreWeight;
        internal int forfeitWeight;
        internal int lookAheadDepth;
        internal ComputerMove move;
        internal Board board;
        internal int color;

        // Defines the difficulty settings.
        public enum Difficulty
        {
            Beginner = 0,
            Intermediate = 1,
            Advanced = 2,
            Expert = 3
        }

        public Agent()
        {
            behavior = new FullSailAFI.GamePlaying.MinimaxBehavior(this);
            scoreWeight = 0;
            forfeitWeight = 0;
            lookAheadDepth = 0;
            board = null;
            move = null;
            color = 0;
        }

        public void setBehavior(Behavior _behavior)
        {
            behavior = _behavior;
        }

        //
        // Sets the AI parameters based on the current difficulty setting.
        //
        public void SetAIParameters(Difficulty difficulty)
        {
            // Set the AI parameter weights.
            switch (difficulty)
            {
                case Difficulty.Beginner:
                    this.scoreWeight = 1;
                    this.forfeitWeight = 4;
                    break;
                case Difficulty.Intermediate:
                    this.scoreWeight = 1;
                    this.forfeitWeight = 6;
                    break;
                case Difficulty.Advanced:
                    this.scoreWeight = 1;
                    this.forfeitWeight = 8;
                    break;
                case Difficulty.Expert:
                    this.scoreWeight = 1;
                    this.forfeitWeight = 10;
                    break;
                default:
                    this.scoreWeight = 0;
                    this.forfeitWeight = 0;
                    break;
            }

            this.lookAheadDepth = (int) difficulty + 1;
        }

        public void SetLookAheadDepth(int _lookAheadDepth)
        {
            lookAheadDepth = _lookAheadDepth;
        }

        public ComputerMove GetMove()
        {
            // Run the behavior to determine a move. On failure, returns null.
            behavior.run();
            return move;
        }
    }
}
